package app.ods;

import app.dim.DimBrandProcessor;
import app.dim.DimCategoryProcessor;
import app.dim.DimShopProcessor;
import app.dwd.DwdMarketContentProcessor;
import app.dwd.DwdMarketProductProcessor;
import app.dwd.DwdMarketSearchProcessor;
import app.dws.*;
import utils.MyClickHouseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 市场分析系统主启动类
 * 提供启动整个系统或单个组件的方法
 */
public class MarketAnalysisSystem {
    
    private static final Logger logger = LoggerFactory.getLogger(MarketAnalysisSystem.class);
    
    /**
     * 主方法，提供系统启动入口
     */
    public static void main(String[] args) {
        logger.info("市场分析系统启动...");
        
        // 测试ClickHouse连接是否正常
        testClickHouseConnection();
        
        // 根据参数决定启动模式
        if (args.length > 0) {
            String mode = args[0];
            switch (mode.toLowerCase()) {
                case "all":
                    startAllComponents();
                    break;
                case "generator":
                    startDataGenerator();
                    break;
                case "dim":
                    startDimensionProcessors();
                    break;
                case "dwd":
                    startFactProcessors();
                    break;
                case "dws":
                    startAnalysisProcessors();
                    break;
                default:
                    logger.warn("未知的启动模式: {}", mode);
                    printUsage();
            }
        } else {
            // 默认只打印帮助信息
            printUsage();
        }
    }
    
    /**
     * 打印使用说明
     */
    private static void printUsage() {
        logger.info("市场分析系统使用说明:");
        logger.info("java -jar market-analysis.jar [mode]");
        logger.info("  mode  - 启动模式:");
        logger.info("    all        - 启动所有组件");
        logger.info("    generator  - 仅启动数据生成器");
        logger.info("    dim        - 仅启动维度表处理器");
        logger.info("    dwd        - 仅启动事实表处理器");
        logger.info("    dws        - 仅启动分析处理器");
    }
    
    /**
     * 测试ClickHouse连接是否正常
     */
    private static void testClickHouseConnection() {
        logger.info("测试ClickHouse连接...");
        boolean connected = MyClickHouseUtil.testConnection();
        if (!connected) {
            logger.warn("ClickHouse连接测试失败，系统可能无法正常工作");
        }
    }
    
    /**
     * 启动所有组件
     */
    private static void startAllComponents() {
        logger.info("启动所有组件...");
        
        // 先启动数据生成器
        startDataGenerator();
        
        // 等待一会儿，确保数据生成器有足够时间生成初始数据
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            logger.error("等待数据生成器时出错", e);
        }
        
        // 启动维度表处理器
        startDimensionProcessors();
        
        // 等待一会儿，确保维度表有数据
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            logger.error("等待维度表时出错", e);
        }
        
        // 启动事实表处理器
        startFactProcessors();
        
        // 等待一会儿，确保事实表有数据
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            logger.error("等待事实表时出错", e);
        }
        
        // 启动分析处理器
        startAnalysisProcessors();
        
        logger.info("所有组件启动完成");
    }
    
    /**
     * 启动数据生成器
     */
    private static void startDataGenerator() {
        logger.info("启动数据生成器...");
        
        Thread generatorThread = new Thread(() -> {
            try {
                // 启动数据生成器
                MarketDataGenerator.main(new String[]{});
            } catch (Exception e) {
                logger.error("数据生成器启动失败", e);
            }
        });
        generatorThread.setName("data-generator-thread");
        generatorThread.start();
    }
    
    /**
     * 启动维度表处理器
     */
    private static void startDimensionProcessors() {
        logger.info("启动维度表处理器...");
        
        // 启动类目维度表处理器
        startProcessorThread("category-dim-processor", () -> {
            try {
                DimCategoryProcessor.main(new String[]{});
            } catch (Exception e) {
                logger.error("类目维度表处理器启动失败", e);
            }
        });
        
        // 启动品牌维度表处理器
        startProcessorThread("brand-dim-processor", () -> {
            try {
                DimBrandProcessor.main(new String[]{});
            } catch (Exception e) {
                logger.error("品牌维度表处理器启动失败", e);
            }
        });
        
        // 启动店铺维度表处理器
        startProcessorThread("shop-dim-processor", () -> {
            try {
                DimShopProcessor.main(new String[]{});
            } catch (Exception e) {
                logger.error("店铺维度表处理器启动失败", e);
            }
        });
    }
    
    /**
     * 启动事实表处理器
     */
    private static void startFactProcessors() {
        logger.info("启动事实表处理器...");
        
        // 启动商品事实表处理器
        startProcessorThread("product-fact-processor", () -> {
            try {
                DwdMarketProductProcessor.main(new String[]{});
            } catch (Exception e) {
                logger.error("商品事实表处理器启动失败", e);
            }
        });
        
        // 启动搜索关键词事实表处理器
        startProcessorThread("search-fact-processor", () -> {
            try {
                DwdMarketSearchProcessor.main(new String[]{});
            } catch (Exception e) {
                logger.error("搜索关键词事实表处理器启动失败", e);
            }
        });
        
        // 启动内容事实表处理器
        startProcessorThread("content-fact-processor", () -> {
            try {
                DwdMarketContentProcessor.main(new String[]{});
            } catch (Exception e) {
                logger.error("内容事实表处理器启动失败", e);
            }
        });
    }
    
    /**
     * 启动分析处理器
     */
    private static void startAnalysisProcessors() {
        logger.info("启动分析处理器...");
        
        // 启动商品榜单处理器
        startProcessorThread("product-rank-processor", () -> {
            try {
                DwsMarketProductRank.main(new String[]{});
            } catch (Exception e) {
                logger.error("商品榜单处理器启动失败", e);
            }
        });
        
        // 启动店铺榜单处理器
        startProcessorThread("shop-rank-processor", () -> {
            try {
                DwsMarketShopRank.main(new String[]{});
            } catch (Exception e) {
                logger.error("店铺榜单处理器启动失败", e);
            }
        });
        
        // 启动内容榜单处理器
        startProcessorThread("content-rank-processor", () -> {
            try {
                DwsMarketContentRank.main(new String[]{});
            } catch (Exception e) {
                logger.error("内容榜单处理器启动失败", e);
            }
        });
        
        // 启动搜索排行处理器
        startProcessorThread("search-rank-processor", () -> {
            try {
                DwsMarketSearchRank.main(new String[]{});
            } catch (Exception e) {
                logger.error("搜索排行处理器启动失败", e);
            }
        });
        
        // 启动类目挖掘处理器
        startProcessorThread("category-mining-processor", () -> {
            try {
                DwsMarketCategoryMining.main(new String[]{});
            } catch (Exception e) {
                logger.error("类目挖掘处理器启动失败", e);
            }
        });
        
        // 启动类目洞察处理器
        startProcessorThread("category-insight-processor", () -> {
            try {
                DwsMarketCategoryInsight.main(new String[]{});
            } catch (Exception e) {
                logger.error("类目洞察处理器启动失败", e);
            }
        });
    }
    
    /**
     * 启动处理器线程的通用方法
     */
    private static void startProcessorThread(String threadName, Runnable task) {
        Thread thread = new Thread(task);
        thread.setName(threadName);
        thread.start();
        
        // 短暂等待，避免线程启动过于密集
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            logger.error("等待线程启动时出错", e);
        }
    }
}